
// INCLUDES ********************************************************************

#include "ParallaxContainer.h"

#include "Sprite.h"

#include "Configuration.h"

#include "Texture2D.h"



// GLOBALS *********************************************************************

// NAMESPACES ******************************************************************

using namespace Meteor;


#pragma mark -
#pragma mark Constructor
// -----------------------------------------------------------------------------

ParallaxContainer::ParallaxContainer()

: DrawableContainer()
{
    
}

// -----------------------------------------------------------------------------

ParallaxContainer::ParallaxContainer( const std::string& backgroundImage)

: DrawableContainer()
{
    Sprite* background = new Sprite( backgroundImage, 0);
    
    background->SetAnchorPoint( 0.0f, 0.0f);
 
    AddChild( background);
}

// -----------------------------------------------------------------------------

ParallaxContainer::~ParallaxContainer()
{
    
}

// -----------------------------------------------------------------------------

void ParallaxContainer::MoveBy( const Vector2D& distance)
{
    containerType::iterator child = mChildren.begin();
    
    child++;
    
    while ( child != mChildren.end())
    {
        Drawable* currentChild = ( *child).first;
    
        currentChild->MoveBy( distance.X()*(currentChild->IndexZ()+1),
                              distance.Y());

        Vector2D positionInBounds = AdjustChildPositionToBounds( currentChild, distance);

        currentChild->SetPosition( positionInBounds);

        child++;
    }
}

// -----------------------------------------------------------------------------

const Vector2D ParallaxContainer::AdjustChildPositionToBounds( Drawable* child, const Vector2D& distance)
{
    const Vector2D position = child->Position();
            
    const Vector2D size = child->Size();

    const Vector2D anchorPoint = child->AnchorPoint();
    
    const Vector2D screenSize = Configuration::Instance().ValueForKey<Vector2D>( "Screensize");

    Vector2D newPosition( position);
    
    float boundary = 0.0f;

    float offsetX = position.X();
    
    float offsetY = position.Y();
    
    /// @todo: can we solve this more flexible?
    if ( distance.X() < 0.0f)
    {
        boundary = -size.X();
        
        const float sizeOffset = size.X()*anchorPoint.X();
        
        if ( position.X() < boundary)
        {
            offsetX = screenSize.X() + sizeOffset;
        }
    }
    else
    {
        boundary = screenSize.X();
        
        const float sizeOffset = size.X()*anchorPoint.X();
        
         if ( position.X()-sizeOffset > boundary)
        {
            offsetX = sizeOffset;
        }
    }
    
    if ( distance.Y() < 0.0f)
    {
        boundary = -size.Y();
        
        const float sizeOffset = size.Y()*anchorPoint.Y();
        
        if ( position.Y() < boundary)
        {
            offsetY = screenSize.Y() + sizeOffset;
        }
    }
    else
    {
        boundary = screenSize.Y();
        
        const float sizeOffset = size.Y()*anchorPoint.Y();
        
         if ( position.Y()-sizeOffset > boundary)
        {
            offsetY = sizeOffset;
        }
    }
    
    newPosition.SetX( offsetX);
    
    newPosition.SetY( offsetY);
    
    return newPosition;
}

// -----------------------------------------------------------------------------

void ParallaxContainer::Update( const float deltaTime)
{
    DrawableContainer::Update( deltaTime);
}